package com.fzrskj.cloud.free.dic.utils;

import com.alibaba.fastjson.JSONObject;
import com.fzrskj.cloud.free.consts.CConsts;
import com.fzrskj.cloud.free.core.enums.PriceTypeEnum;
import com.fzrskj.cloud.free.core.enums.ProductTypeEnum;
import com.fzrskj.cloud.free.core.enums.PromotionEnum;
import com.fzrskj.cloud.free.core.tool.CDateTimeTool;
import com.fzrskj.cloud.free.core.tool.CJsonTool;
import com.fzrskj.cloud.free.core.tool.CStrTool;
import com.fzrskj.cloud.free.core.utils.CloudContextUtils;
import com.fzrskj.cloud.free.core.utils.DoubleUtil;
import com.fzrskj.cloud.free.dic.bean.DicVipgrade;
import com.fzrskj.cloud.free.dic.utils.vo.CloudAgentPriceVo;
import com.fzrskj.cloud.free.miniservice.utils.DiyProductPriceUtils;
import com.fzrskj.cloud.free.sys.bean.SysProductView;
import com.fzrskj.cloud.free.sys.bean.SysPromotion;
import com.fzrskj.cloud.free.sys.utils.SysDiyProductPriceUtils;
import com.fzrskj.cloud.free.sys.utils.SysProductUtils;
import com.fzrskj.cloud.free.sys.utils.SysPromotionUtils;
import com.fzrskj.cloud.free.user.bean.UserAccount;
import com.fzrskj.cloud.free.user.bean.UserAccountView;
import com.fzrskj.cloud.free.user.bean.UserDiyBean;
import com.fzrskj.cloud.free.user.dao.UserAccountDao;
import com.fzrskj.cloud.free.user.utils.UserAccountUtils;
import com.fzrskj.cloud.free.user.utils.UserDiyUtils;
import com.winiis.component.common.utils.other.MapOperateUtils;
import ms.core.consts.SysErr;
import ms.core.object.CObject;
import ms.core.tool.StrTool;
import ms.core.tool.XmlCodeParser;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.map.HashedMap;

import java.util.*;

/**
 * DicPriceDiyUtils.
 *
 * @author zj.
 * Created on 2019/1/15 0015.
 */
public class DicPriceDiyUtils extends CObject {

    private String PRODUCT_CLASS = ProductTypeEnum.DIY.getTag();

    /**
     * 获取自定义商品价格.
     *
     * @param cdt {productCode, applyTime, priceType, num, chargeId}
     * @return String of json.
     */
    public String getPrice(Map<String, Object> cdt) {
        UserAccountDao accountDao = new UserAccountDao();
        Integer agentId = cdt.containsKey("_agentId") ? MapUtils.getInteger(cdt, "_agentId") : CloudContextUtils.getAgentId();
        Integer chargeId = 1;
        JSONObject result = new JSONObject();
        if (cdt.containsKey("chargeId")) {
            chargeId = Integer.valueOf(cdt.get("chargeId").toString());
        }
        do {
            //diy renew price
            if (chargeId == 2 && cdt.containsKey("id")) {
                result = getDiyRenewPrice(Integer.valueOf(cdt.get("id").toString()), cdt.get("priceType").toString());
            }

            if (result.size() > 0) {
                break;
            }

            Map<String, Object> productCdt = new HashedMap();
            productCdt.put("productClass", ProductTypeEnum.DIY.getTag());
            productCdt.put("productCode", cdt.get("productCode"));
            String productCode = MapUtils.getString(cdt, "productCode");
            SysProductUtils sysProductUtils = new SysProductUtils();
            SysProductView productView = sysProductUtils.querySysProduct(productCdt);
            String code = sysProductUtils.getErrCode();
            if (!code.equals(SysErr.CODE_SUCCESS)) {
                return XmlCodeParser.formatResultTips(false, code);
            }

            //合并主平台产品基础数据
            productView = agentProductMergeSysProductParam(productView);

            JSONObject productParam = JSONObject.parseObject(productView.getProductParam());
            if (null == productParam) {
                return XmlCodeParser.formatResultTips(false, "PRODUCT_CONFIG_ERROR", "产品参数配置错误");
            }

            //get product sale type
            int priceSaleType = null != productParam && productParam.containsKey("saleType") ? productParam.getInteger("saleType") : 1;
            int userId = cdt.containsKey("userId") ? Integer.valueOf(cdt.get("userId").toString()): 0;
            String userLevel = getAgentUserLevelCode();

            //折前总价
            Double totalPrice;
            String priceType = MapOperateUtils.getStr(cdt, "priceType");
            Integer applyTime = MapOperateUtils.getInt(cdt, "applyTime");
            Double price = productParam.getDouble("price");


            //自定义参数，需要通过询价接口获取
            String paramShow = productParam.getString("paramShow");
            if ("diy".equals(paramShow)) {
                String miniServer = productParam.getString("miniServer");
                //删除平台保护数据
                cdt.remove("productCode");

                DiyProductPriceUtils priceUtils = new DiyProductPriceUtils();
                if (chargeId == 1) {
                    totalPrice = priceUtils.getPrice(miniServer, cdt);
                } else if (chargeId == 2) {
                    totalPrice = priceUtils.getRenewPrice(miniServer, cdt);
                } else {
                    return XmlCodeParser.formatResultTips(false, "NOT_SUPPORT_CHARGE", "不支持的价格类型");
                }
                if (null == totalPrice) {
                    return XmlCodeParser.formatResultTips(false, priceUtils.getErrCode(), priceUtils.getMsg());
                }
                price = DoubleUtil.divide(totalPrice, Double.valueOf(PriceTypeEnum.MONTH.equals(priceType) ? applyTime : (applyTime * 12)));
            } else {

                Integer num = MapOperateUtils.getInt(cdt, "num");
                if (priceSaleType == 2) {
                    //todo hl831 按会员等级取价格
                    Map<String, Object> obj = new HashMap<>();
                    obj.put("productClass", ProductTypeEnum.DIY.getTag());
                    obj.put("productCode", productCode);
                    obj.put("chargeId", chargeId);
                    obj.put("levelCode", userLevel);
                    SysDiyProductPriceUtils sysDiyProductPriceUtils = new SysDiyProductPriceUtils();
                    Double nprice = Double.valueOf(sysDiyProductPriceUtils.getDomainProductPrice(applyTime, priceType , obj));
                    sysDiyProductPriceUtils.dispose();
                    totalPrice = DoubleUtil.mul(nprice, Double.valueOf(num));
                } else {
                    Integer applyMonth = 0;
                    switch (priceType) {
                        case "m":
                            applyMonth = applyTime;
                            break;
                        default:
                            applyMonth = applyTime * 12;
                            break;
                    }
                    //折前总价
                    totalPrice = DoubleUtil.mul(price, Double.valueOf(applyMonth * num));
                }

            }
            List<SysPromotion> promotionList = new ArrayList<>();

            Map<String, Object> param = new HashMap<>();
            param.put("productCode", productView.getProductCode());
            param.put("chargeId", chargeId);
            param.put("agentId", CloudContextUtils.DEF_AGENT_ID);
            if (priceSaleType == 2) {
                //todo hl831 按会员等级取价格
                SysDiyProductPriceUtils sysDiyProductPriceUtils = new SysDiyProductPriceUtils();
                promotionList = sysDiyProductPriceUtils.getDiyProductBuyTime(param);
                sysDiyProductPriceUtils.dispose();
            } else {
                //产品促销列表
                SysPromotionUtils promotionUtils = new SysPromotionUtils();
                promotionList = promotionUtils.getSysPromotionList(param);
            }


            //是否允许销售
            boolean isAllowSell = false;
            //Boolean exists = false;
            Integer saleType = 0;
            Double saleValue = Double.valueOf(0);
            if (!promotionList.isEmpty()) {
                for (SysPromotion sysPromotion : promotionList) {
                    if (applyTime.equals(sysPromotion.getApplyTime()) && priceType.equals(sysPromotion.getApplyType())) {
                        isAllowSell = true;
                        saleType = sysPromotion.getSaleType();
                        if (!StrTool.isBlankStr(sysPromotion.getSaleValue())) {
                            saleValue = Double.valueOf(sysPromotion.getSaleValue());
                        }
                    }
                }
            }

            Double discountPrice = new Double(0);

            //折后价
            Double realPrice = totalPrice;
            if (PromotionEnum.MONTH.equals(saleType)) {
                discountPrice = DoubleUtil.mul(Double.valueOf(saleValue), price);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            } else if (saleType == 2) {
                Double oldTotalPrice = realPrice;
                realPrice = DoubleUtil.divide(DoubleUtil.mul(oldTotalPrice, saleValue), new Double(10));
                discountPrice = DoubleUtil.sub(oldTotalPrice, realPrice);
            } else if (saleType == 3) {
                Double dayPrice = DoubleUtil.divide(price, Double.valueOf(CConsts.MONTH_DAY));
                discountPrice = DoubleUtil.mul(dayPrice, saleValue);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            }

            //以上为平台成本价，接下来是代理溢价
            //add
            if (chargeId == 1) {
                //if ( priceSaleType != 2) {
                    Integer buyOperation = 1;
                    CloudAgentPriceVo priceVo = CloudAgentPriceUtils.computeAgentPriceDiy(
                            productCode, buyOperation, totalPrice, realPrice, agentId, priceSaleType!=2);
                    if (!priceVo.getComputeResult()) {
                        result.put("totalPrice", DoubleUtil.round(0, 2));
                        result.put("payPrice", DoubleUtil.round(0, 2));
                        result.put("discountPrice", DoubleUtil.round(0, 2));
                        break;
                    }
                    totalPrice = priceVo.getTotalPrice();
                    realPrice = priceVo.getPayPrice();
                //}
            }

            //renew
            if (chargeId == 2) {
                //以上为平台成本价，接下来是代理溢价
                if (agentId > 0) {
                    if (cdt.containsKey("_agentId")) {
                        UserAccount account = accountDao.getUserAccountWithoutAgent(agentId);
                        agentId = account.getAgentId();
                        cdt.put("userId", account.getUserId());
                    }

                    Integer buyOperation = 1;
                    CloudAgentPriceVo priceVo = CloudAgentPriceUtils.computeAgentPriceDiy(
                            productCode, buyOperation, totalPrice, realPrice, agentId, priceSaleType != 2);
                    if (!priceVo.getComputeResult()) {
                        result.put("totalPrice", DoubleUtil.round(0, 2));
                        result.put("payPrice", DoubleUtil.round(0, 2));
                        result.put("discountPrice", DoubleUtil.round(0, 2));
                        break;
                    }
                    totalPrice = priceVo.getTotalPrice();
                    realPrice = priceVo.getPayPrice();
                }
            }
            //总价格
            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));

            //会员等级价
            if (cdt.containsKey("userId") ) {
                //主平台会员设置按会员等级设置价格时，不打折
                if (!CloudContextUtils.getAgentId().equals(CloudContextUtils.DEF_AGENT_ID) || priceSaleType != 2) {
                    DicVipgradeUtils dvUtils = new DicVipgradeUtils();
                    DicVipgrade ua = dvUtils.queryDicVipgradeByUidAppointAgent(userId, agentId);
                    if (ua != null) {
                        if (ua.getRebate() > 0) {
                            realPrice = DoubleUtil.mul(realPrice, ua.getRebate() / 10);
                        }
                    }
                }

            }

            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));
            result.put("payPrice", DoubleUtil.round(realPrice, 2));
            result.put("discountPrice", DoubleUtil.round(discountPrice, 2));

            //不让销售时，价格为0
            if (!isAllowSell) {
                result.put("totalPrice", DoubleUtil.round(0, 2));
                result.put("payPrice", DoubleUtil.round(0, 2));
                result.put("discountPrice", DoubleUtil.round(0, 2));
            }

        } while (false);

        return XmlCodeParser.formatResultData(true, SysErr.CODE_SUCCESS, JSONObject.toJSONString(result));
    }

    public String getUpgradePrice(Integer userId, Integer id, Map<String, Object> params) {
        //获取开通参数
        UserDiyUtils diyUtils = new UserDiyUtils();
        UserDiyBean bean = diyUtils.queryUserDiy(id);
        if (null == bean) {
            return XmlCodeParser.formatResultTips(false, "DIY BUSINESS NOT FOUND", "自定义业务不存在");
        }

        Map<String, Object> cdt = new HashMap<String, Object>();
        cdt.put("productCode", bean.getProductCode());
        cdt.put("applyTime", bean.getApplyTime());
        cdt.put("priceType", bean.getPriceType());
        cdt.put("num", 1);
        cdt.put("chargeId", 1);
        if (userId > 0) {
            cdt.put("userId", userId);
        }

        JSONObject openInfo = JSONObject.parseObject(bean.getOpenInfo());
        JSONObject orderParams = openInfo.getJSONObject("diy_params");
        if (null == orderParams) {
            orderParams = new JSONObject();
        }
        orderParams.put("number", 1);
        orderParams.put("period", bean.getApplyTime());
        orderParams.put("period_unit", PriceTypeEnum.MONTH.equals(bean.getPriceType()) ? "month" : "year");
        cdt.putAll(orderParams);

        String priceOld = this.getPrice(cdt);
        net.sf.json.JSONObject priceObject = CJsonTool.getJSONObject(priceOld, "data", null);
        if (null == priceObject || !priceObject.containsKey("totalPrice")) {
            return priceOld;
        }
        Double totalPrice = priceObject.getDouble("totalPrice");
        Double payPrice = priceObject.getDouble("payPrice");

        //其他参数
        cdt.putAll(params);
        cdt.put("productCode", bean.getProductCode());
        cdt.put("applyTime", bean.getApplyTime());
        cdt.put("priceType", bean.getPriceType());
        cdt.put("num", 1);
        cdt.put("chargeId", 1);
        String priceNew = this.getPrice(cdt);
        net.sf.json.JSONObject priceNewObject = CJsonTool.getJSONObject(priceNew, "data", null);
        if (!priceNewObject.containsKey("totalPrice")) {
            return priceNew;
        }
        Double totalPriceNew = priceNewObject.getDouble("totalPrice");
        Double payPriceNew = priceNewObject.getDouble("payPrice");
        if (totalPrice > totalPriceNew || payPrice > payPriceNew || payPriceNew > totalPriceNew) {
            return XmlCodeParser.formatResultTips(false, "DIY UPGRADE PRICE ERROR", "自定义业务升级价格错误");
        }

        //总差价。
        Double totalDiscountPrice = DoubleUtil.sub(totalPriceNew, totalPrice);
        Double payDiscountPrice = DoubleUtil.sub(payPriceNew, payPrice);

        //差价均价
        Integer totalDays = bean.getApplyTime().intValue() * (PriceTypeEnum.MONTH.equals(bean.getPriceType()) ? CConsts.MONTH_DAY : CConsts.YEAR_DAY);
        Double totalUnitPrice = DoubleUtil.divide(totalDiscountPrice, totalDays.doubleValue());
        Double payUnitPrice = DoubleUtil.divide(payDiscountPrice, totalDays.doubleValue());

        //实附价格
        Integer days = CDateTimeTool.daysBetween(new Date(), bean.getEndTime());
        Double totalRealPrice = DoubleUtil.mul(totalUnitPrice, days.doubleValue());
        Double payRealPrice = DoubleUtil.mul(payUnitPrice, days.doubleValue());

        JSONObject result = new JSONObject();
        result.put("totalPrice", DoubleUtil.round(totalRealPrice, 2));
        result.put("payPrice", DoubleUtil.round(payRealPrice, 2));
        result.put("discountPrice", DoubleUtil.sub(totalRealPrice, payRealPrice, 2));

        return XmlCodeParser.formatResultData(true, SysErr.CODE_SUCCESS, JSONObject.toJSONString(result));
    }

    private JSONObject getDiyRenewPrice(int id, String priceType) {
        JSONObject result = new JSONObject();
        UserDiyUtils diyUtils = new UserDiyUtils();
        do {

            UserDiyBean diy = diyUtils.queryUserDiy(id);
            if (null == diy) {
                break;
            }

            if (CStrTool.isBlankStr(priceType)) {
                priceType = PriceTypeEnum.YEAR.getFlag();
            }

            diy = UserDiyUtils.setDefRenewPirce(diy);
            if (diy.getRenewMonthPrice() > 0 || diy.getRenewYearPrice() > 0) {

                if (diy.getRenewMonthPrice() > 0 && priceType.equals(PriceTypeEnum.MONTH.getFlag())) {
                    result.put("totalPrice", DoubleUtil.round(diy.getRenewMonthPrice(), 2));
                    result.put("payPrice", DoubleUtil.round(diy.getRenewMonthPrice(), 2));
                    result.put("discountPrice", DoubleUtil.round(diy.getRenewMonthPrice(), 2));
                }
                if (diy.getRenewYearPrice() > 0 && priceType.equals(PriceTypeEnum.YEAR.getFlag())) {
                    result.put("totalPrice", DoubleUtil.round(diy.getRenewYearPrice(), 2));
                    result.put("payPrice", DoubleUtil.round(diy.getRenewYearPrice(), 2));
                    result.put("discountPrice", DoubleUtil.round(diy.getRenewYearPrice(), 2));
                }
            }
        } while (false);
        diyUtils.dispose();
        return result;
    }

    /**
     * 获取自定义商品新购价格
     *
     * @param cdt {productCode, applyTime, priceType, num, chargeId}
     * @return String of json.
     */
    public String getAddPrice(Map<String, Object> cdt) {
        int uAgentId = CloudContextUtils.getAgentId();
        Integer agentId = cdt.containsKey("_agentId") ? MapUtils.getInteger(cdt, "_agentId") : uAgentId;
        Integer chargeId = 1;
        String productCode = MapUtils.getString(cdt, "productCode");
        int userId = cdt.containsKey("userId") ? Integer.valueOf(cdt.get("userId").toString()): 0;

        JSONObject result = new JSONObject();

        SysProductUtils sysProductUtils = new SysProductUtils();
        SysDiyProductPriceUtils sysDiyProductPriceUtils = new SysDiyProductPriceUtils();

        do {

            Map<String, Object> productCdt = new HashedMap();
            productCdt.put("productClass", PRODUCT_CLASS);
            productCdt.put("productCode", productCode);
            SysProductView productView = sysProductUtils.querySysProduct(productCdt);
            String code = sysProductUtils.getErrCode();
            if (!code.equals(SysErr.CODE_SUCCESS)) {
                this.setErrCode(code);
                break;
            }

            //合并主平台产品基础数据
            productView = agentProductMergeSysProductParam(productView);

            JSONObject productParam = JSONObject.parseObject(productView.getProductParam());
            if (null == productParam) {
                this.setErrCode("PRODUCT_CONFIG_ERROR", "产品参数配置错误");
                break;
            }

            //get product sale type
            int priceSaleType = getProductPriceSetType(productView);
            String userLevel = getAgentUserLevelCode();

            //折前总价
            Double totalPrice;
            String priceType = MapOperateUtils.getStr(cdt, "priceType");
            Integer applyTime = MapOperateUtils.getInt(cdt, "applyTime");
            Double price = productParam.getDouble("price");

            //自定义参数，需要通过询价接口获取
            String paramShow = productParam.getString("paramShow");
            if ("diy".equals(paramShow)) {
                String miniServer = productParam.getString("miniServer");
                //删除平台保护数据
                cdt.remove("productCode");

                DiyProductPriceUtils priceUtils = new DiyProductPriceUtils();
                if (chargeId == 1) {
                    totalPrice = priceUtils.getPrice(miniServer, cdt);
                } else if (chargeId == 2) {
                    totalPrice = priceUtils.getRenewPrice(miniServer, cdt);
                } else {
                    return XmlCodeParser.formatResultTips(false, "NOT_SUPPORT_CHARGE", "不支持的价格类型");
                }

                if (null == totalPrice) {
                    return XmlCodeParser.formatResultTips(false, priceUtils.getErrCode(), priceUtils.getMsg());
                }
                price = DoubleUtil.divide(totalPrice, Double.valueOf(PriceTypeEnum.MONTH.equals(priceType) ? applyTime : (applyTime * 12)));
            } else {
                totalPrice = getFirstTotalPrice(priceSaleType, MapOperateUtils.getInt(cdt, "num"), price, PRODUCT_CLASS, productCode, chargeId, userLevel, priceType, applyTime);
            }

            //产品促销列表
            List<SysPromotion> promotionList = getPromotionList(productView.getProductCode(), chargeId, priceSaleType);

            //是否允许销售

            //是否允许销售
            boolean isAllowSell = false;
            Integer saleType = 0;
            Double saleValue = Double.valueOf(0);
            if (!promotionList.isEmpty()) {
                for (SysPromotion sysPromotion : promotionList) {
                    if (applyTime.equals(sysPromotion.getApplyTime()) && priceType.equals(sysPromotion.getApplyType())) {
                        isAllowSell = true;
                        saleType = sysPromotion.getSaleType();
                        if (!StrTool.isBlankStr(sysPromotion.getSaleValue())) {
                            saleValue = Double.valueOf(sysPromotion.getSaleValue());
                        }
                    }
                }
            }

            Double discountPrice = new Double(0);

            //折后价
            Double realPrice = totalPrice;
            if (PromotionEnum.MONTH.equals(saleType)) {
                discountPrice = DoubleUtil.mul(Double.valueOf(saleValue), price);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            } else if (saleType == 2) {
                Double oldTotalPrice = realPrice;
                realPrice = DoubleUtil.divide(DoubleUtil.mul(oldTotalPrice, saleValue), new Double(10));
                discountPrice = DoubleUtil.sub(oldTotalPrice, realPrice);
            } else if (saleType == 3) {
                Double dayPrice = DoubleUtil.divide(price, Double.valueOf(CConsts.MONTH_DAY));
                discountPrice = DoubleUtil.mul(dayPrice, saleValue);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            }

            //以上为平台成本价，接下来是代理溢价

            //if (priceSaleType != 2) {
            Integer buyOperation = 1;
            //该方法为获取成本价，所以需要跳过本级代理溢价设置
            if (agentId > 0) {
                UserAccountUtils accountUtils = new UserAccountUtils();
                UserAccountView accountView = accountUtils.queryUserAccountWithoutAgent(agentId);
                if (accountView.getAgentId() > 0) {
                    CloudAgentPriceVo priceVo = CloudAgentPriceUtils.computeAgentPriceDiy(
                            productCode, buyOperation, totalPrice, realPrice, accountView.getAgentId(), true);
                    if (!priceVo.getComputeResult()) {
                        result.put("totalPrice", DoubleUtil.round(0, 2));
                        result.put("payPrice", DoubleUtil.round(0, 2));
                        result.put("discountPrice", DoubleUtil.round(0, 2));
                        break;
                    }
                    totalPrice = priceVo.getTotalPrice();
                    realPrice = priceVo.getPayPrice();
                }
            }

            //总价格
            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));

            //会员等级价
            if (cdt.containsKey("userId") ) {
                //主平台会员设置按会员等级设置价格时，不打折
                if (!CloudContextUtils.getAgentId().equals(CloudContextUtils.DEF_AGENT_ID) || priceSaleType != 2) {
                    DicVipgradeUtils dvUtils = new DicVipgradeUtils();
                    DicVipgrade ua = dvUtils.queryDicVipgradeByUidAppointAgent(userId, agentId);
                    if (ua != null) {
                        if (ua.getRebate() > 0) {
                            realPrice = DoubleUtil.mul(realPrice, ua.getRebate() / 10);
                        }
                    }
                }
            }

            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));
            result.put("payPrice", DoubleUtil.round(realPrice, 2));
            result.put("discountPrice", DoubleUtil.round(discountPrice, 2));

            //不让销售时，价格为0
            if (!isAllowSell) {
                result.put("totalPrice", DoubleUtil.round(0, 2));
                result.put("payPrice", DoubleUtil.round(0, 2));
                result.put("discountPrice", DoubleUtil.round(0, 2));
            }

        } while (false);
        sysDiyProductPriceUtils.dispose();
        return result.toJSONString();
    }

    /**
     * 获取自定义商品新购价格
     *
     * @param cdt {productCode, applyTime, priceType, num, chargeId}
     * @return String of json.
     */
    public String getRenewPrice(Map<String, Object> cdt) {
        UserAccountDao accountDao = new UserAccountDao();
        Integer agentId = cdt.containsKey("_agentId") ? MapUtils.getInteger(cdt, "_agentId") : CloudContextUtils.getAgentId();
        Integer chargeId = 1;
        int userId = cdt.containsKey("userId") ? Integer.valueOf(cdt.get("userId").toString()): 0;
        String productCode = MapUtils.getString(cdt, "productCode");
        JSONObject result = new JSONObject();

        SysProductUtils sysProductUtils = new SysProductUtils();
        do {
            //diy renew price
            if (cdt.containsKey("id")) {
                result = getDiyRenewPrice(Integer.valueOf(cdt.get("id").toString()), cdt.get("priceType").toString());
            }

            if (result.size() > 0) {
                break;
            }

            Map<String, Object> productCdt = new HashedMap();
            productCdt.put("productClass", PRODUCT_CLASS);
            productCdt.put("productCode", productCode);
            SysProductView productView = sysProductUtils.querySysProduct(productCdt);
            String code = sysProductUtils.getErrCode();
            if (!code.equals(SysErr.CODE_SUCCESS)) {
                this.setErrCode(code);
                break;
            }

            //合并主平台产品基础数据
            productView = agentProductMergeSysProductParam(productView);

            JSONObject productParam = JSONObject.parseObject(productView.getProductParam());
            if (null == productParam) {
                this.setErrCode("PRODUCT_CONFIG_ERROR", "产品参数配置错误");
                break;
            }

            //get product sale type
            int priceSaleType = getProductPriceSetType(productView);
            String userLevel = getAgentUserLevelCode();

            //折前总价
            Double totalPrice;
            String priceType = MapOperateUtils.getStr(cdt, "priceType");
            Integer applyTime = MapOperateUtils.getInt(cdt, "applyTime");
            Double price = productParam.getDouble("price");


            //自定义参数，需要通过询价接口获取
            String paramShow = productParam.getString("paramShow");
            if ("diy".equals(paramShow)) {
                String miniServer = productParam.getString("miniServer");
                //删除平台保护数据
                cdt.remove("productCode");

                DiyProductPriceUtils priceUtils = new DiyProductPriceUtils();
                if (chargeId == 1) {
                    totalPrice = priceUtils.getPrice(miniServer, cdt);
                } else if (chargeId == 2) {
                    totalPrice = priceUtils.getRenewPrice(miniServer, cdt);
                } else {
                    return XmlCodeParser.formatResultTips(false, "NOT_SUPPORT_CHARGE", "不支持的价格类型");
                }
                if (null == totalPrice) {
                    return XmlCodeParser.formatResultTips(false, priceUtils.getErrCode(), priceUtils.getMsg());
                }
                price = DoubleUtil.divide(totalPrice, Double.valueOf(PriceTypeEnum.MONTH.equals(priceType) ? applyTime : (applyTime * 12)));
            } else {
                totalPrice = getFirstTotalPrice(priceSaleType, MapOperateUtils.getInt(cdt, "num"), price, PRODUCT_CLASS, productCode, chargeId, userLevel, priceType, applyTime);
            }

            List<SysPromotion> promotionList = getPromotionList(productCode, chargeId, priceSaleType);

            //是否允许销售
            boolean isAllowSell = false;
            Integer saleType = 0;
            Double saleValue = Double.valueOf(0);
            if (!promotionList.isEmpty()) {
                for (SysPromotion sysPromotion : promotionList) {
                    if (applyTime.equals(sysPromotion.getApplyTime()) && priceType.equals(sysPromotion.getApplyType())) {
                        isAllowSell = true;
                        saleType = sysPromotion.getSaleType();
                        if (!StrTool.isBlankStr(sysPromotion.getSaleValue())) {
                            saleValue = Double.valueOf(sysPromotion.getSaleValue());
                        }
                    }
                }
            }

            Double discountPrice = new Double(0);

            //折后价
            Double realPrice = totalPrice;
            if (PromotionEnum.MONTH.equals(saleType)) {
                discountPrice = DoubleUtil.mul(Double.valueOf(saleValue), price);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            } else if (saleType == 2) {
                Double oldTotalPrice = realPrice;
                realPrice = DoubleUtil.divide(DoubleUtil.mul(oldTotalPrice, saleValue), new Double(10));
                discountPrice = DoubleUtil.sub(oldTotalPrice, realPrice);
            } else if (saleType == 3) {
                Double dayPrice = DoubleUtil.divide(price, Double.valueOf(CConsts.MONTH_DAY));
                discountPrice = DoubleUtil.mul(dayPrice, saleValue);
                totalPrice = DoubleUtil.add(totalPrice, discountPrice);
            }

            //以上为平台成本价，接下来是代理溢价
            if (agentId > 0) {
                if (cdt.containsKey("_agentId")) {
                    UserAccount account = accountDao.getUserAccountWithoutAgent(agentId);
                    agentId = account.getAgentId();
                    cdt.put("userId", account.getUserId());
                }

                Integer buyOperation = 1;
                CloudAgentPriceVo priceVo = CloudAgentPriceUtils.computeAgentPriceDiy(
                        productCode, buyOperation, totalPrice, realPrice, agentId, priceSaleType!=2);
                if (!priceVo.getComputeResult()) {
                    result.put("totalPrice", DoubleUtil.round(0, 2));
                    result.put("payPrice", DoubleUtil.round(0, 2));
                    result.put("discountPrice", DoubleUtil.round(0, 2));
                    break;
                }
                totalPrice = priceVo.getTotalPrice();
                realPrice = priceVo.getPayPrice();
            }

            //总价格
            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));

            //会员等级价
            if (cdt.containsKey("userId") ) {
                //主平台会员设置按会员等级设置价格时，不打折
                if (!CloudContextUtils.getAgentId().equals(CloudContextUtils.DEF_AGENT_ID) || priceSaleType != 2) {
                    DicVipgradeUtils dvUtils = new DicVipgradeUtils();
                    DicVipgrade ua = dvUtils.queryDicVipgradeByUidAppointAgent(userId, agentId);
                    if (ua != null) {
                        if (ua.getRebate() > 0) {
                            realPrice = DoubleUtil.mul(realPrice, ua.getRebate() / 10);
                        }
                    }
                }
            }
            //不让销售时，价格为0
            if (!isAllowSell) {
                result.put("totalPrice", DoubleUtil.round(0, 2));
                result.put("payPrice", DoubleUtil.round(0, 2));
                result.put("discountPrice", DoubleUtil.round(0, 2));
                break;
            }
            result.put("totalPrice", DoubleUtil.round(totalPrice, 2));
            result.put("payPrice", DoubleUtil.round(realPrice, 2));
            result.put("discountPrice", DoubleUtil.round(discountPrice, 2));


        } while (false);

        return result.toJSONString();
    }

    /**
     * 获取平台价格等级
     * @return
     */
    public static String getAgentUserLevelCode(){
        String levelCode = DicParamUtils.getParamValue("showPriceLevel");
        UserAccountDao accountDao = new UserAccountDao();
        UserAccount userAccount = accountDao.getUserAccountWithoutAgent(UserAccountUtils.getTopAgentUserId(CloudContextUtils.getAgentId()));
        if (userAccount != null) {
            levelCode = userAccount.getLevelCode();
        }
        accountDao.dispose();
        return levelCode;
    }

    /**
     * 合并主站产品参数
     * @param product
     * @return
     */
    public static SysProductView agentProductMergeSysProductParam(SysProductView product){
        SysProductUtils sysProductUtils = new SysProductUtils();
        if (CloudContextUtils.getAgentId() > 0) {
            SysProductView viewPlat = sysProductUtils.querySysProductAppointAgent(product.getProductClass(), product.getProductCode(),
                    product.getRegType(), CloudContextUtils.DEF_AGENT_ID);
            net.sf.json.JSONObject paramPlat = net.sf.json.JSONObject.fromObject(viewPlat.getProductParam());
            net.sf.json.JSONObject sysProductParam = net.sf.json.JSONObject.fromObject(product.getProductParam());
            paramPlat.putAll(sysProductParam);
            product.setProductParam(paramPlat.toString());
        }
        sysProductUtils.dispose();
        return product;
    }

    /**
     * 获取价格设置类型 1-会员折扣 2-按会员等级设置价格。。。
     * @param product
     * @return
     */
    public static Integer getProductPriceSetType(SysProductView product){
        Integer priceSaleType = 1;
        JSONObject productParam = JSONObject.parseObject(product.getProductParam());
        if (null != productParam) {
            priceSaleType = productParam.containsKey("saleType") ? productParam.getInteger("saleType") : 1;
        }
        return priceSaleType;
    }

    /**
     * 获取销售月份
     * @return
     */
    private Integer getSaleMonth(String priceType, Integer applyTime){
        Integer applyMonth;
        switch (priceType) {
            case "m":
                applyMonth = applyTime;
                break;
            default:
                applyMonth = applyTime * 12;
                break;
        }
        return applyMonth;
    }

    /**
     * 获取自定义产品按系统配置的总价
     * @param priceSaleType
     * @param num
     * @param price
     * @param productClass
     * @param productCode
     * @param chargeId
     * @param userLevel
     * @param priceType
     * @param applyTime
     * @return
     */
    private Double getFirstTotalPrice(int priceSaleType, Integer num, Double price, String productClass, String productCode, int chargeId, String userLevel, String priceType, int applyTime) {
        Double totalPrice = 0.0;
        SysDiyProductPriceUtils sysDiyProductPriceUtils = new SysDiyProductPriceUtils();
        Map<String, Object> obj = new HashMap<>();
        if (priceSaleType == 2) {
            //按会员等级取价格
            obj.put("productClass", productClass);
            obj.put("productCode", productCode);
            obj.put("chargeId", chargeId);
            obj.put("levelCode", userLevel);
            Double nprice = Double.valueOf(sysDiyProductPriceUtils.getDomainProductPrice(applyTime, priceType, obj));
            totalPrice = DoubleUtil.mul(nprice, Double.valueOf(num));
        } else {
            //折前总价
            totalPrice = DoubleUtil.mul(price, Double.valueOf(getSaleMonth(priceType, applyTime)) * num);
        }
        sysDiyProductPriceUtils.dispose();
        return totalPrice;
    }

    /**
     * 获取可购买时长
     * @param productCode
     * @param chargeId
     * @param priceSaleType
     * @return
     */
    private List<SysPromotion> getPromotionList(String productCode, int chargeId, int  priceSaleType){
        List<SysPromotion> list;
        SysPromotionUtils promotionUtils = new SysPromotionUtils();

        SysDiyProductPriceUtils sysDiyProductPriceUtils = new SysDiyProductPriceUtils();
        Map<String, Object> cdt = new HashMap<>();
        cdt.put("productCode", productCode);
        cdt.put("chargeId", chargeId);
        cdt.put("agentId", CloudContextUtils.DEF_AGENT_ID);
        if (priceSaleType == 2) {
            list = sysDiyProductPriceUtils.getDiyProductBuyTime(cdt);
        } else {
            list = promotionUtils.getSysPromotionList(cdt);
        }
        sysDiyProductPriceUtils.dispose();
        promotionUtils.dispose();
        return list;
    }


    /**
     *
     * @param list
     * @param applyTime
     * @param priceType
     * @param saleType
     * @param saleValue
     * @return
     */
    private Boolean isAllowSell(List<SysPromotion> list, int applyTime, String priceType,Integer saleType, Double saleValue){
        //是否允许销售
        boolean isAllowSell = false;
        if (!list.isEmpty()) {
            for (SysPromotion sysPromotion : list) {
                if (applyTime == sysPromotion.getApplyTime() && priceType.equals(sysPromotion.getApplyType())) {
                    isAllowSell = true;
                    saleType = sysPromotion.getSaleType();
                    if (!StrTool.isBlankStr(sysPromotion.getSaleValue())) {
                        saleValue = Double.valueOf(sysPromotion.getSaleValue());
                    }
                }
            }
        }
        return isAllowSell;
    }

}
